//
// Created by Amon on 2021/10/16.
//

#include "SignalHandler.h"

void signal_handle(int signal_num, struct siginfo *si, void *sc) {
    LOGE("捕捉到了native的崩溃");
    signal(signal_num, SIG_DFL);
    signal(SIGALRM, SIG_DFL);
    (void) alarm(8);
    notify_thread_exception(signal_num, si, sc);
    default_handlers[signal_num].sa_sigaction(signal_num, si, sc);
}

void installAlternateStack() {
    stack_t new_stack;
    stack_t old_stack;
    memset(&old_stack, 0, sizeof(old_stack));
    memset(&new_stack, 0, sizeof(new_stack));
    static const unsigned sigaltstack_size = std::max(40960, SIGSTKSZ);

    if (sigaltstack(nullptr, &old_stack) == -1
            || !old_stack.ss_sp
            || old_stack.ss_size < sigaltstack_size) {
        new_stack.ss_sp = calloc(1, sigaltstack_size);
        if (sigaltstack(&new_stack, nullptr) == -1) {
            free(new_stack.ss_sp);
        }
    }
}

bool installSignalHandlers() {
    LOGE("installSignalHandler");
    for (int i = 0; i < EXCEPTION_SIGNALS_NUMBER; i++) {
        int ret = sigaction(EXCEPTION_SIGNALS[i], nullptr, &default_handlers[EXCEPTION_SIGNALS[i]]);
        if (ret == -1) {
            LOGE("SET SIGNAL ACTION ERROR:%d", i);
            return false;
        }
    }

    struct sigaction crash_sigaction{};
    memset(&crash_sigaction, 0, sizeof(crash_sigaction));
    sigemptyset(&crash_sigaction.sa_mask);
    crash_sigaction.sa_flags = SA_ONSTACK | SA_SIGINFO;
    crash_sigaction.sa_sigaction = signal_handle;

    for (int i : EXCEPTION_SIGNALS) {
        sigaddset(&crash_sigaction.sa_mask, i);
    }

    for (int i = 0; i < EXCEPTION_SIGNALS_NUMBER; i++) {
        int ret = sigaction(EXCEPTION_SIGNALS[i], &crash_sigaction, nullptr);
        if (ret == -1) {
            LOGE("SET SIGNAL ACTION ERROR:%d", i);
            return false;
        }
    }
    return true;
}
